package com.bigworld;

import com.bigworld.MCWorld;
import Jama.Matrix;

public class Gufeng extends MCWorld{
	short[][][] block=null;
	byte[][][] blockid=null;
	public Gufeng(MCWorld mc){
		super(mc);
	}
	public Gufeng(){
		super();
	}
	public String test(){
		for(int i=0;i<29;i++)
			if(i%2!=1)
				eaves(0,19,i,0, (v,o)->{tile_44_0(v.x,v.y,v.z,v.a);return v;});
			else
				eaves2(0,19,i,0, (v,o)->{tile_44_6(v.x,v.y,v.z,v.a);return v;});
		copy(-13,12,0,14,8,29);
		paste(0,(vt,o)->{
			return new Vector4i(1*2-(vt.x-13), vt.y+12, vt.z, 0);
		});
		line(1,19,0,1,19,29,1);
		line(1,20,-1,1,20,30,44);

		return endWorld();
	}
	public void copy(int x,int y,int z,int lx,int ly,int lz){
		block = new short[lx][ly][lz];
		blockid = new byte[lx][ly][lz];
		for(int i=0;i<lx;i++)
			for(int j=0;j<ly;j++)
				for(int k=0;k<lz;k++){
					block[i][j][k] = getBlock(x+i,y+j,z+k);
					blockid[i][j][k] = (byte)getData(x+i,y+j,z+k);
				}

	}
	public void paste(int x,int y,int z){
		int lx=block.length,ly=block[0].length,lz=block[0][0].length;
		for(int i=0;i<lx;i++)
			for(int j=0;j<ly;j++)
				for(int k=0;k<lz;k++){
					setBlock(x+i,y+j,z+k,block[i][j][k]);
					setData(x+i,y+j,z+k,blockid[i][j][k]);
				}
	}
	public void paste(Object o,TmpEvent tm){
		int lx=block.length,ly=block[0].length,lz=block[0][0].length;
		for(int i=0;i<lx;i++)
			for(int j=0;j<ly;j++)
				for(int k=0;k<lz;k++){
					Vector4i tv = tm.e(new Vector4i(i,j,k,1),o);
					setBlock(tv.x,tv.y,tv.z,block[i][j][k]);
					setData(tv.x,tv.y,tv.z,blockid[i][j][k]);
				}
	}
	interface TmpEvent{
		public Vector4i e(Vector4i v,Object o);
	}
	//x:-14,y:-8
	public void eaves(int lx,int ly,int lz,int ls,TmpEvent mate){
		ls = lx-ls;
		for(int x=0;x<3;x++)
			for(int y=0;y<3;y++)
				if(lx-x<=ls)
					mate.e(new Vector4i(lx-x,ly-x,0-y,lz),null);
		for(int x=3;x<7;x++)
			for(int y=3;y<5;y++)
				if(lx-x<=ls)
					mate.e(new Vector4i(lx-x,ly,0-y-x,lz),null);
		for(int i=7;i<9;i++)
			if(lx-i<=ls)
				mate.e(new Vector4i(lx-i,ly,0-10,lz),null);
		for(int i=8;i<11;i++)
			if(lx-i<=ls)
				mate.e(new Vector4i(lx-i,ly,0-11,lz),null);
		for(int i=10;i<14;i++)
			if(lx-i<=ls)
				mate.e(new Vector4i(lx-i,ly,0-12,lz),null);
	}
	public void eaves2(int lx,int ly,int lz,int ls,TmpEvent mate){
		ls = lx-ls;
		for(int x=0;x<3;x++)
			for(int y=0;y<3;y++)
				if(lx-x<=ls)
					mate.e(new Vector4i(lx-x,ly-x,0-1-y,lz),null);
		for(int x=3;x<7;x++)
			for(int y=3;y<5;y++)
				if(lx-x<=ls)
					mate.e(new Vector4i(lx-x,ly,0-1-y-x,lz),null);
		for(int i=7;i<9;i++)
			if(lx-i<=ls)
				mate.e(new Vector4i(lx-i,ly,0-1-10,lz),null);
		for(int i=8;i<11;i++)
			if(lx-i<=ls)
				mate.e(new Vector4i(lx-i,ly,0-1-11,lz),null);
		for(int i=10;i<13;i++)
			if(lx-i<=ls)
				mate.e(new Vector4i(lx-i,ly,0-1-12,lz),null);
	}
	public void tile_44_6(int x, int y1, int y2, int z){
		//44_6,44_14
		//112
		int block = 44,slot = 6;
		int block2 = 112;
		y1 = y1+(y2/2);
		y2 = y2%2;
		if(y2<0){
			y1--; y2=1;
		}
		if(getBlock(x, y1, z)==block && getData(x, y1, z)==(slot+8-y2*8)){
			point(x,y1,z,block2);
			setData(x,y1,z,(byte)0);
		}else{
			point(x,y1,z,block);
			setData(x,y1,z,(byte)(slot+y2*8));
		}
	}
	public void tile_44_0(int x, int y1, int y2, int z){
		//44_0,44_8
		//43
		int block = 44,slot = 0;
		int block2 = 43;
		y1 = y1+(y2/2);
		y2 = y2%2;
		if(y2<0){
			y1--; y2=1;
		}
		if(getBlock(x, y1, z)==block && getData(x, y1, z)==(slot+8-y2*8)){
			point(x,y1,z,block2);
			setData(x,y1,z,(byte)0);
		}else{
			point(x,y1,z,block);
			setData(x,y1,z,(byte)(slot+y2*8));
		}
	}
	public void random_map(){
		int l = 10;
		int m = (int)Math.pow(2, l);
		int[][] mh = new int[m][m];
		for(int i=0;i<m;i++)
			for(int j=0;j<m;j++)
				mh[i][j] = -1;
		mh[m-1][m-1] = 50;
	    for(int i=l-1;i>=0;i--){
	    	int n = (int)Math.pow(2, i);
	    	for(int j=n-1;j<m;j+=2*n)
	    		for(int k=n-1;k<m;k+=2*n){
	    			wm2(mh, j, k, i, m, (int)((Math.random()-0.5)*Math.pow(2, i)));
	    		}
	    	for(int j=n-1;j<m;j+=n)
	    		for(int k=n-1;k<m;k+=n){
	    			wm(mh, j, k, i, m, (int)((Math.random()-0.5)*Math.pow(2, i)));
	    		}
	    }
		for(int i=0;i<m;i++)
			for(int j=0;j<m;j++){
				int len = mh[i][j]>255?255:mh[i][j];
				len = mh[i][j]<0?0:mh[i][j];
				line(i, 0, j, i, len, j, 35);
				contour(i, 0, j, i, len, j);
			}
	}
	public void wm(int[][] map, int x, int y, int l, int m, int rand){
		int r = (int)Math.pow(2, l);
		if(map[x][y] == -1){
			int ave_height = (map[(x+r)%m][y] + map[x][(y+r)%m] + map[(x-r+m)%m][y] + map[x][(y-r+m)%m])/4;
			map[x][y] = ave_height+rand;
		}
	}
	public void wm2(int[][] map, int x, int y, int l, int m, int rand){
		int r = (int)Math.pow(2, l);
		if(map[x][y] == -1){
			int ave_height = (map[(x+r)%m][(y+r)%m] + map[(x+r)%m][(y-r+m)%m] + map[(x-r+m)%m][(y+r)%m] + map[(x-r+m)%m][(y-r+m)%m])/4;
			map[x][y] = ave_height+rand;
		}
	}
}